import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { HomeController } from './business/home/home.controller';
import { HomeService } from './business/home/home.service';
import { TimerMiddleware } from './middlewares/timer.middleware';
import { PrismaModule } from './common/prisma/prisma.module';
import { UsersModule } from './business/users/users.module';
import { PostsModule } from './business/posts/posts.module';
import { ProfilesModule } from './business/profiles/profiles.module';
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { HttpExceptionFilter } from './filters/http-exception.filter';
import { AuthModule } from './business/auth/auth.module';
import { AuthGuard } from './guards/auth.guard';
import { LoggingInterceptor } from './interceptors/logging.interceptor';
import { ExcludeNullInterceptor } from './interceptors/exclude-null.interceptor';
import { NotifyMailModule } from './pilot/dynamic-module/notify-mail/notify-mail.module';
import { NotifySmsModule } from './pilot/dynamic-module/notify-sms/notify-sms.module';
import { InjectModule } from './pilot/inject-scope/inject.module';
import { MichaelModule } from './pilot/circular-dependency/michael/micheal.module';
import { MoonModule } from './pilot/circular-dependency/moon/moon.module';
import { ModuleRefModule } from './pilot/module-reference/module-ref.module';
import { LazyLoadingModule } from './pilot/lazying-module/lazying-loading.module';
import { VerifyGuard } from './guards/verify.guard';
import { ErrorFilter } from './filters/common-error.filter';
import { ShutdownModule } from './pilot/lifecycle-event/shutdown.module';
import { DiscoveryServiceModule } from './pilot/discovery-service/discovery.module';
import { CacheInterceptor, CacheModule } from '@nestjs/cache-manager';
import { CustomizedCacheModule } from './cache/cache.module';
import { ScheduleModule } from '@nestjs/schedule';
import { CustomScheduleModule } from './schedule/schedule.module';
import { CookieModule } from './cookie/cookie.module';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { CustomEventEmitterModule } from './event-emitter/event-emitter.module';
import { FileUploadModule } from './upload/file-upload.module';
import { FileStreamModule } from './stream/file-stream.module';
import { CatsModule } from '@business/cats/cats.module';
import { HttpCatsModule } from './http/http-cat.module';
import { ConfigModule } from '@nestjs/config';
import { CustomSseModule } from './sse/sse.module';
import { CustomSseEnhanceModule } from './sse-enhance/sse-enhance.module';
@Module({
  // Business modules register
  imports: [
    PrismaModule,
    // Cats Module
    CatsModule,
    // Http Cats Module
    HttpCatsModule,
    UsersModule, PostsModule,
    ProfilesModule, AuthModule,
    // Modules for Dynamic Module
    NotifyMailModule,
    NotifySmsModule,
    // Module for Inject Scope
    InjectModule,
    // Module for Circular Dependency Demo
    MichaelModule, MoonModule,
    // Module for Module Reference
    ModuleRefModule,
    // Module for Lazy Loading
    LazyLoadingModule,
    // Lifecycle Event
    // ShutdownModule,
    // DiscoveryModule,
    DiscoveryServiceModule,
    // For Cache
    CacheModule.register({
      isGlobal: true,
      ttl: 10000, // 10 seconds
      stores: [],
      max: 100, // 最大缓存数量
      logger: console,
      logLevels: ['verbose'], // print verbose log
    }),
    // Customized Cache Module
    CustomizedCacheModule, // AppModule 导入的模块, 不会 自动共享 给所有子模块, 子模块需要主动导入才能使用. 除非给模块设置 @Global
    // ScheduleModule: 定时任务模块
    ScheduleModule.forRoot(),
    // Custom Schedule Module
    CustomScheduleModule,
    // Cookie Module
    CookieModule,
    EventEmitterModule.forRoot({
      // 设置为 `true` 以使用通配符
      wildcard: false,
      // 用于分割命名空间的分隔符
      delimiter: '.',
      // 如果您希望触发 newListener 事件，请设置为 `true`
      newListener: false,
      // 如果您希望触发 removeListener 事件，请设置为 `true`
      removeListener: false,
      // 可以分配给事件的最大监听器数量
      maxListeners: 10,
      // 当监听器数量超过最大值时，在内存泄漏消息中显示事件名称
      verboseMemoryLeak: false,
      // 当错误事件被触发且没有监听器时，禁用抛出 uncaughtException
      ignoreErrors: false,
    }
    ),
    // Custom Event Emitter Module
    CustomEventEmitterModule,
    // File Upload Module
    FileUploadModule,
    // File Stream Module
    FileStreamModule,
    // ConfigModule
    ConfigModule.forRoot({ isGlobal: true, envFilePath: '.env' }),
    // Sse Module
    CustomSseModule,
    // Custom Sse Enhance Module
    CustomSseEnhanceModule,
  ],
  controllers: [HomeController],
  providers: [
    HomeService,
    { provide: APP_FILTER, useClass: ErrorFilter, },
    { provide: APP_FILTER, useClass: HttpExceptionFilter, },
    /**
     * Enable authentication globally
     * With this in place, Nest will automatically bind AuthGuard to all endpoints.
    */
    { provide: APP_GUARD, useClass: AuthGuard },
    { provide: APP_GUARD, useClass: VerifyGuard },
    /**
     * Enable logging globally
     * With this in place, Nest will automatically bind LoggingInterceptor to all endpoints.
    */
    { provide: APP_INTERCEPTOR, useClass: LoggingInterceptor },
    /**
     * Enable exclude null globally
     * With this in place, Nest will automatically bind ExcludeNullInterceptor to all endpoints.
    */
    { provide: APP_INTERCEPTOR, useClass: ExcludeNullInterceptor },
    /**
     * Custom provider
    */
    {
      provide: APP_INTERCEPTOR,
      useClass: CacheInterceptor,
    },
  ],
})
export class AppModule implements NestModule {
  // middleware config
  async configure(consumer: MiddlewareConsumer) {
    consumer.apply(TimerMiddleware).forRoutes('*');
  }
}
